package com.zj.cman.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {

    /*private static final SecretKey SIGNING_KEY;
    static {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256");
            keyGen.init(256); // 生成 256 位密钥
            SIGNING_KEY = keyGen.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException("无法生成 HMAC-SHA-256 密钥", e);
        }
    }*/

    // 定义一个对称密钥，用于签名和验证 JWT。在实际应用中，应该通过更安全的方式管理密钥。
    private static final String SECRET_KEY = "GgwTqx9oa6dSWFqH3RuyRHmHCEixYVJBcU09aYTibkA="; // 请确保此字符串是 Base64 编码的 256 位密钥
    // 密钥转换为 Java Key 对象
    private static final Key SIGNING_KEY = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());

    private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 24 hours

    /**
     * 创建一个 JWT token
     *
     * @param subject   主题（通常是用户标识符）
     * @param claims    自定义声明（如角色、权限等）
     * @param ttlMillis 过期时间（以毫秒为单位）
     * @return 生成的 JWT 字符串
     */
    public static String createToken(String subject, Map<String, Object> claims, long ttlMillis) {
        // 设置签发时间和过期时间
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + ttlMillis);

        // 使用 Jwts.builder() 构建 JWT
        return Jwts.builder()
                .setClaims(claims)           // 添加自定义声明
                .setSubject(subject)         // 设置主题
                .setIssuedAt(now)            // 设置签发时间
                .setExpiration(expiryDate)   // 设置过期时间
                .signWith(SIGNING_KEY, SignatureAlgorithm.HS256) // 使用 HS256 算法签名
                .compact();                  // 将所有信息压缩成一个紧凑的 JWT 字符串
    }

    /**
     * 解析并验证 JWT token
     *
     * @param token 需要解析的 JWT 字符串
     * @return 包含有效载荷信息的 Claims 对象
     * @throws Exception 如果解析或验证失败，则抛出异常
     */
    public static Claims parseToken(String token) throws Exception {
        try {
            // 使用 Jwts.parserBuilder() 构建 JwtParser 并解析 JWT
            return Jwts.parser()
                    .setSigningKey(SIGNING_KEY)
                    .build()
                    .parseClaimsJws(token) // 注意这里调用的是 parseClaimsJws
                    .getBody();
        } catch (ExpiredJwtException e) {
            throw new Exception("JWT 已过期", e);
        } catch (UnsupportedJwtException e) {
            throw new Exception("不支持的 JWT 格式", e);
        } catch (MalformedJwtException e) {
            throw new Exception("无效的 JWT 格式", e);
        } catch (Exception e) {
            throw new Exception("JWT 解析失败", e);
        }
    }

    /**
     * 示例：创建带有自定义声明的 JWT
     */
    public static void main(String[] args) {
        //生成秘钥
        /*byte[] secretKeyBytes = new byte[32]; // 256 bits
        new SecureRandom().nextBytes(secretKeyBytes);
        String encodedKey = Base64.getEncoder().encodeToString(secretKeyBytes);
        System.out.println(encodedKey);*/
        // 创建自定义声明
        Map<String, Object> claims = new HashMap<>();
        claims.put("role", "admin");
        claims.put("email", "user@example.com");

        // 创建 JWT
        String jwt = createToken("John Doe", claims, EXPIRATION_TIME); // 24小时有效期
        System.out.println("Generated JWT: " + jwt);

        // 解析并验证 JWT
        try {
            Claims body = parseToken(jwt);
            System.out.println("Subject: " + body.getSubject());
            System.out.println("Role: " + body.get("role"));
            System.out.println("Email: " + body.get("email"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}